package org.iteam.core.freemarker;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.iteam.core.shiro.AuthUtils;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;

public class AuthDirective implements TemplateDirectiveModel {

	private static final String PARAM_NAME_COUNT = "code";

	@SuppressWarnings({ "rawtypes", "unused" })
	public void execute(Environment env, Map params, TemplateModel[] loopVars,
			TemplateDirectiveBody body) throws TemplateException, IOException {

		// ---------------------------------------------------------------------
		// 处理参数

		String countParam = null;
		boolean countParamSet = false;
		boolean hrParam = false;

		Iterator paramIter = params.entrySet().iterator();
		while (paramIter.hasNext()) {
			Map.Entry ent = (Map.Entry) paramIter.next();

			String paramName = (String) ent.getKey();
			TemplateModel paramValue = (TemplateModel) ent.getValue();

			if (paramName.equals(PARAM_NAME_COUNT)) {
				if (!(paramValue instanceof TemplateScalarModel)) {
					throw new TemplateModelException("The \""
							+ PARAM_NAME_COUNT + "\" parameter "
							+ "must be a number.");
				}
				countParam = paramValue + "";
				countParamSet = true;
				if (countParam == null) {
					throw new TemplateModelException("The \""
							+ PARAM_NAME_COUNT + "\" parameter "
							+ "can't be not null.");
				}
			}
			if (!countParamSet) {
				throw new TemplateModelException("The required \""
						+ PARAM_NAME_COUNT + "\" paramter" + "is missing.");
			}

			if (loopVars.length > 1) {
				throw new TemplateModelException(
						"At most one loop variable is allowed.");
			}

			// Yeah, it was long and boring...
			try {
				// ---------------------------------------------------------------------
				// 真正开始处理输出内容
				// Writer out = env.getOut();
				// 输出 <hr> 如果 参数hr 设置为true
				// out.write("<hr>");
				// 验证是否拥有权限
				Subject subject = SecurityUtils.getSubject();
				String url = countParam;
				switch (AuthUtils.validate(url)) {
				// -2:禁止访问
				case -2:
					break;
				// -1: 不要验证
				case -1:
					if (body != null) {
						// 执行标签内容(same as <#nested> in FTL).
						body.render(env.getOut());
					}
					break;
				// 0:需要验证允许通过
				case 0:
					if (subject.isPermitted(url) || AuthUtils.isPermission(url))
						if (body != null) {
							// 执行标签内容(same as <#nested> in FTL).
							body.render(env.getOut());
						}
					break;
				// 1:需要验证禁止通过
				case 1:
					if (!subject.isPermitted(url)
							&& !AuthUtils.isPermission(url))
						if (body != null) {
							// 执行标签内容(same as <#nested> in FTL).
							body.render(env.getOut());
						}
					break;
				// 2:只验证是否登录SecurityUtils
				case 2:
					if (subject.isAuthenticated())
						if (body != null) {
							// 执行标签内容(same as <#nested> in FTL).
							body.render(env.getOut());
						}
					break;
				default:
					break;
				}

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}